from __future__ import with_statement

import os
from contest.util import iter_sources, mtimes
import time
import re
import fnmatch
import tempfile

# Some system's mtime resolution is too low. (about 1 sec.)
#   ; adjust sleep time.
def mtime_resolution():
    fn = tempfile.mktemp()
    with open(fn, 'w') as f: pass
    try:
        t1 = os.path.getmtime(fn)
        os.utime(fn, (t1 + 0.1, t1 + 0.1))
        t2 = os.path.getmtime(fn)
        if t1 == t2:
            return 1
        else:
            return 0.2
    finally:
        try:
            os.unlink(fn)
        except OSError:
            pass

resolution = mtime_resolution()

def walker_norecur(d):
    yield (d,
           [],
           [fn for fn in os.listdir(d) if os.path.isfile(fn)]
    )

class Monitor:
    def __init__(self, path, pattern, recursive=True):
        self.path = path
        if isinstance(pattern, str):
            fn = pattern
            self.walker = lambda d: [(d, [], [fn])]
            pattern = re.compile(fnmatch.translate(pattern))
        elif recursive:
            self.walker = os.walk
        else:
            self.walker = walker_norecur
        self.pattern = pattern
        self.status = self.walk()
       
    def changed(self):
        new = self.walk()
        if new - self.status:
            self.status = new
            return True
        else:
            return False
    def walk(self):
        return mtimes(self.path, walker=self.walker, pattern=self.pattern)

def mainloop(path, pattern, callback, recursive=True):
    monitor = Monitor(os.curdir, pattern, recursive)
    callback()
    while 1:
        time.sleep(resolution)
        if monitor.changed():
            callback()
